package com.sunny.openplatformutils.utils;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * 
 * @author Sunny
 *
 */
public final class JsonUtil extends ObjectMapper {

	public JsonUtil() {
		super();
		// 序列化时忽略空值
		this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		// 序列化时忽略空对象
		this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		// 反序列化时忽略不存在属性
		this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

	/**
	 *
	 * @param serializationInclusion			序列化值处理方式
	 * @param failOnUnknownProperties		反序列化不存在属性校验
	 */
	public JsonUtil(JsonInclude.Include serializationInclusion, boolean failOnUnknownProperties) {
		super();
		// 序列化时忽略空值
		this.setSerializationInclusion(serializationInclusion);
		// 序列化时忽略空对象
		this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		// 反序列化时忽略不存在属性
		this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);
	}

	private static final JsonUtil json = new JsonUtil();

	/**
	 * to json
	 * @param obj
	 * @return
	 * @throws IOException
	 */
	public static String toJson(Object obj) throws IOException {
		return json.writeValueAsString(obj);
	}

	/**
	 * parse json as Object
	 * @param json
	 * @param clazz
	 * @return
	 * @throws IOException 
	 */
	public static <T> T parse(String json, Class<T> clazz) throws IOException {
		return JsonUtil.json.readValue(json, clazz);
	}
	
	/**
	 * parse JsonNode as Object
	 * @param node
	 * @param clazz
	 * @return
	 * @throws IOException
	 */
	public static <T> T parse(JsonNode node, Class<T> clazz) throws IOException {
		return json.readValue(node.traverse(), clazz);
	}

	/**
	 * parse json use TypeReference
	 * @param json
	 * @param typeRef
	 * @return
	 * @throws IOException 
	 */
	public static <T> T parse(String json, TypeReference<T> typeRef) throws IOException {
		return JsonUtil.json.readValue(json, typeRef);
	}
	
	/**
	 * parse json use TypeReference
	 * @param jsonStream
	 * @param typeRef
	 * @return
	 * @throws IOException 
	 */
	public static <T> T parse(InputStream jsonStream, TypeReference<T> typeRef) throws IOException {
		return json.readValue(jsonStream, typeRef);
	}
	
	/**
	 * parse JsonNode as Object
	 * @param node
	 * @param typeRef
	 * @return
	 * @throws IOException
	 */
	public static <T> T parse(JsonNode node, TypeReference<T> typeRef) throws IOException {
		return json.readValue(node.traverse(), typeRef);
	}
	
	/**
	 * parse jsonFile as JsonNode
	 * @param file
	 * @throws IOException 
	 */
	public static JsonNode parse(File file) throws IOException {
		return json.readTree(file);
	}
	
	/**
	 * parse jsonString as JsonNode
	 * @param content
	 * @throws IOException 
	 */
	public static JsonNode parse(String content) throws IOException {
		return json.readTree(content);
	}

}
